package de.dhbw.karlsruhe.picsim.rs232;

import app.Com;
import app.Parameters;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Created by IntelliJ IDEA.
 * User: user
 * Date: May 1, 2010
 * Time: 12:32:19 AM
 */
final class ComHandlerImpl implements ComHandler {
    private static final Log log = LogFactory.getLog(ComHandlerImpl.class);
    private final Collection<Listener> listeners = new CopyOnWriteArraySet<Listener>();
    private final Com com;

    private boolean isActive;

    ComHandlerImpl(final String comPort) throws Exception {
        final Parameters param = new Parameters();
        param.setPort(comPort);
        param.setBaudRate("4800");

        com = new Com(param);
        isActive = true;
        startListeningThread();

    }

    @Override
    public void dispose() {
        try {
            isActive = false;
            listeners.clear();
            com.close();
        } catch (Exception e) {
            log.error(e);
        }

    }

    @Override
    public boolean isReady() {
        return isActive;
    }

    @Override
    public void sendString(@NotNull final String message) {
        log.debug(message);
        try {
            for (int i = 0; i < message.length(); i++) {
                com.sendSingleData(message.charAt(i));
            }
        } catch (Exception e) {
            log.error(e);
        }

    }


    @Override
    public void addListener(@NotNull final Listener listener) {
        listeners.add(listener);

    }

    @Override
    public void removeListener(@NotNull final Listener listener) {
        listeners.remove(listener);

    }

    private void startListeningThread() {
        new Thread(new Runnable() {
            private final StringBuilder currentMessage = new StringBuilder();

            @Override
            public void run() {
                while (isActive) {
                    try {
                        final String character = com.receiveSingleString();
                        if (character.length() != 0) {
                            currentMessage.append(character);
                            if (character.equals(PicViewProtocolImpl.END_OF_MESSAGE)) {
                                final String message = currentMessage.toString();
                                currentMessage.delete(0, currentMessage.length());
                                fireMessage(message);
                            }
                        }
                        Thread.sleep(200);
                    } catch (final Exception e) {
                        log.error(e);
                    }
                }
            }
        }).start();

    }

    private void fireMessage(@NotNull final String message) {
        new Thread(new Runnable() {
            public void run() {
                log.info("Firing Message from Com: " + message);
                for (final Listener listener : listeners) {
                    listener.processMessage(message);

                }
            }
        }).start();
    }
}
